/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.brain.sele.manager;

import com.brain.core.common.UtilCore;
import com.brain.core.configuracion.WebServletContextListener;
import com.brain.core.dto.ParametroDto;
import com.brain.core.manager.*;
import com.brain.core.exception.DAOException;
import com.brain.core.hibernate.dao.DAOGenerico;
import com.brain.core.view.mbean.SessionMBean;
import com.brain.core.view.util.ConstantesCore;
import com.brain.sele.dto.ConvocatoriaDto;
import com.brain.sele.dto.ConvocatoriaEvaluacionDto;
import com.brain.sele.dto.PostulanteDto;
import com.brain.sele.dto.RequerimientoDto;
import com.brain.sele.dto.ResponsableDto;
import com.brain.sele.view.util.ConstantesSele;
import com.brain.sgc.view.util.ConstantesSgc;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

/**
 *
 * @author Hvives
 */
@Service
public class ConvocatoriaManager extends ComunManager<ConvocatoriaDto> implements Serializable {

    private static Logger logger = Logger.getLogger(ConvocatoriaManager.class);
    @Resource
    private RecursosManager recursosManager;
    @Resource
    private ConvocatoriaEvaluacionManager convEvaluaManager;
    @Resource
    private PostulanteManager postulanteManager;
    @Resource
    private DAOGenerico<ConvocatoriaDto> springHibernateDao;
    @Resource
    private ResponsableManager responsableManager;

    public ConvocatoriaDto obtenerConvocatoriaPorId(Long id) throws DAOException {
        return springHibernateDao.obtenerDtoPorId(ConvocatoriaDto.class, id);
    }

    public List<ConvocatoriaDto> obtenerConvocatorias(ConvocatoriaDto dtoFiltro) throws DAOException {
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        List<ConvocatoriaDto> lista = null;
        Map<String, Object> mapFiltro = new HashMap<String, Object>();

        if (dtoFiltro.getId() != null && !dtoFiltro.getId().equals(0L)) {
            mapFiltro.put("id", dtoFiltro.getId());
        }
        if (dtoFiltro.getDescripcion() != null && dtoFiltro.getDescripcion().length() != 0) {
            mapFiltro.put("descripcion", dtoFiltro.getDescripcion());
        }
        if (dtoFiltro.getProcesoDto().getId() != null && !dtoFiltro.getProcesoDto().getId().equals(0L) && !dtoFiltro.getProcesoDto().getId().equals(-1L)) {
            mapFiltro.put("procesoDto.id", dtoFiltro.getProcesoDto().getId());
        }
        if (dtoFiltro.getEstadoDto().getId() != null && !dtoFiltro.getEstadoDto().getId().equals(0L) && !dtoFiltro.getEstadoDto().getId().equals(ConstantesCore.Parametro.TODOS)) {
            mapFiltro.put("estadoDto.id", dtoFiltro.getEstadoDto().getId());
        }
        //Se agrega estas lineas de codigo para obtener las evaluaciones de acuerdo a la organizacion en sesion
        mapFiltro.put("empresaDto.id", sessionMBean.getEmpresaDto().getId());
        if (sessionMBean.getOrganizacionDto() != null) {
            if (sessionMBean.getOrganizacionDto().getId() != null) {
                mapFiltro.put("organizacionDto.id", sessionMBean.getOrganizacionDto().getId());
            }
        }
        Map<String, String> mapOrden = new HashMap<String, String>();
        mapOrden.put("descripcion", "asc");

        try {
            lista = obtenerConFiltroConOrden(mapFiltro, mapOrden);
        } catch (DAOException ex) {
            logger.error("ERROR DE SISTEMA", ex);
        }
        return lista;
    }

    public ConvocatoriaDto inicializar(){
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        ConvocatoriaDto dto = new ConvocatoriaDto();
        dto.setEstadoDto(new ParametroDto(ConstantesSele.Parametro.CONV_ESTADO_ELABORACION));
        dto.setVigencia(10L);
        dto.setEmpresaDto(sessionMBean.getEmpresaDto());
        if (sessionMBean.getOrganizacionDto() != null) {
            if (sessionMBean.getOrganizacionDto().getId() != null) {
                dto.setOrganizacionDto(sessionMBean.getOrganizacionDto());
            }
        }
        return dto;
    }
    
    public ConvocatoriaDto guardar(ConvocatoriaDto dto, List<ConvocatoriaEvaluacionDto> listaConvEva) {

        ConvocatoriaDto to = null;
        String mensajeTrx = "";
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        if (this.validarConvEvaluacion(listaConvEva)) {
            if (sessionMBean.getAccion() == ConstantesSele.Formulario.NUEVO) {
                try {
                    dto.setUsuarioCreacionDto(sessionMBean.getSessionUsuarioDto());
                    dto.setFechaCreacion(UtilCore.Fecha.obtenerFechaActualDate());
                    dto.setTerminalCreacion(sessionMBean.getSessionTerminal());
                    UtilCore.General.toUpperCaseDto(dto);
                    dto.setListaConvocatoriaEvaluacion(new ArrayList<ConvocatoriaEvaluacionDto>());
                    //Guardamos en la tabla convocatoria_evaluacion segun el proceso seleccionado
                    double peso = 0;
                    for (ConvocatoriaEvaluacionDto x : listaConvEva) {
                        x.setConvocatoriaDto(dto);
                        x.setUsuarioCreacion(sessionMBean.getSessionUsuarioDto().getId());
                        x.setFechaCreacion(UtilCore.Fecha.obtenerFechaActualDate());
                        x.setTerminalCreacion(sessionMBean.getSessionTerminal());
                        UtilCore.General.toUpperCaseDto(x);
                        dto.getListaConvocatoriaEvaluacion().add(x);
                        peso += x.getPorcentaje().doubleValue();
                    }
                    dto.setPeso(UtilCore.Numero.round(BigDecimal.valueOf(peso), 2));
                    nuevo(dto);

                    mensajeTrx = UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok");
                    recursosManager.showMessage(mensajeTrx);
                    to = dto;
                } catch (Exception ex) {
                    System.out.println(ex.getCause());
                    ex.getStackTrace();
                    mensajeTrx = ex.getMessage();
                    recursosManager.showError(ex.getMessage());
                    logger.error(mensajeTrx);

                    to = null;
                }
            } else if (sessionMBean.getAccion() == ConstantesSele.Formulario.EDITAR) {
                try {
                    dto.setUsuario(sessionMBean.getSessionUsuarioDto().getId());
                    dto.setFecha(UtilCore.Fecha.obtenerFechaActualDate());
                    dto.setTerminal(sessionMBean.getSessionTerminal());
                    UtilCore.General.toUpperCaseDto(dto);
                    if (!listaConvEva.isEmpty()) {
                        double peso = 0;
                        for (ConvocatoriaEvaluacionDto x : listaConvEva) {
                            peso += x.getPorcentaje().doubleValue();
                            this.convEvaluaManager.editar(x);
                        }
                        dto.setPeso(UtilCore.Numero.round(BigDecimal.valueOf(peso), 2));
                    }
                    editar(dto);

                    mensajeTrx = UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok");
                    recursosManager.showMessage(mensajeTrx);

                    to = dto;
                } catch (Exception ex) {
                    mensajeTrx = ex.getMessage();
                    recursosManager.showError(ex.getMessage());
                    logger.error(mensajeTrx);
                    to = null;
                }
            }
        }
        return to;
    }

    protected Boolean validarConvEvaluacion(List<ConvocatoriaEvaluacionDto> listaConvEva) {
        Boolean resultado = true;
        double porcentaje = 0;
        for (ConvocatoriaEvaluacionDto x : listaConvEva) {
            if (x.getNotaMinimaAprob().compareTo(x.getNotaMaxima()) > 0) {
                recursosManager.showWarning(UtilCore.Internacionalizacion.getMensajeInternacional("convocatoria.mensaje.error_notas") + " " + x.getEvaluacionDto().getDescripcion());
                resultado = false;
            }

            if (UtilCore.Fecha.diferenciaDiasFechas(x.getFechaFin(), x.getFechaInicio()) > 0) {
                recursosManager.showWarning(UtilCore.Internacionalizacion.getMensajeInternacional("convocatoria.mensaje.error_fechas") + " " + x.getEvaluacionDto().getDescripcion());
                resultado = false;
            }

            porcentaje += x.getPorcentaje().doubleValue();
            if (x.getOrden() > 0L && x.getOrden() <= listaConvEva.size()) {
                for (ConvocatoriaEvaluacionDto x1 : listaConvEva) {
                    if (x.getOrden().equals(x1.getOrden()) && !x.getEvaluacionDto().getId().equals(x1.getEvaluacionDto().getId())) {
                        recursosManager.showWarning(UtilCore.Internacionalizacion.getMensajeInternacional("convocatoria.mensaje.error_orden") + " " + x.getEvaluacionDto().getDescripcion());
                        resultado = false;
                    }
                }
            } else {
                recursosManager.showWarning(UtilCore.Internacionalizacion.getMensajeInternacional("convocatoria.mensaje.error_orden") + " " + x.getEvaluacionDto().getDescripcion());
                resultado = false;
            }
        }

        if (porcentaje <= 0) {
            recursosManager.showWarning(UtilCore.Internacionalizacion.getMensajeInternacional("convocatoria.mensaje.error_porcentaje"));
            resultado = false;
        }

        return resultado;
    }

    protected String validarPublicacion(ConvocatoriaDto dto) {
        String msg = "";
        //Verificamos los miembros del comite >=1
        if (dto.getListaMiembroComite().size() < ConstantesSele.ValoresConstantes.CONV_NUM_MINIMO_MIEMBROS_COMITE) {
            msg = UtilCore.Internacionalizacion.getMensajeInternacional("convocatoria.msg.val.miem_comite");
            return msg;
        }
        //Verificamos los requerimientos >=1
        if (dto.getListaConvocaRequerimiento().size() < ConstantesSele.ValoresConstantes.CONV_NUM_MINIMO_REQUERIMIENTOS) {
            msg = UtilCore.Internacionalizacion.getMensajeInternacional("convocatoria.msg.val.requerimientos");
            return msg;
        }
        if (dto.getProcesoDto().getTipo().equals(ConstantesSgc.ValoresConstantes.PROCESO_TIPO_COD_PUBLICO)) {
            //Verificamos los medios de difusion >=1
            if (dto.getListaConvMedioDifu().size() < ConstantesSele.ValoresConstantes.CONV_NUM_MINIMO_MEDIO_DIFU) {
                msg = UtilCore.Internacionalizacion.getMensajeInternacional("convocatoria.msg.val.medio_difusion");
                return msg;
            }
        }
        //Verificamos los responsables por req - etapa
        try {
            if (dto.getListaConvocaRequerimiento().size() > 0) {
                for (RequerimientoDto req : dto.getListaConvocaRequerimiento()) {
                    for (ResponsableDto resp : this.responsableManager.obtenerResponsablesPorReq(req.getId())) {
                        if (resp.getMiembroComiteDto() == null) {
                            msg = UtilCore.Internacionalizacion.getMensajeInternacional("convocatoria.msg.val.resp_por_etapa");
                            return msg;
                        }
                    }
                    if (dto.getProcesoDto().getTipo().equals(ConstantesSgc.ValoresConstantes.PROCESO_TIPO_COD_INTERNO)) {
                        List<PostulanteDto> listaPost = this.postulanteManager.obtenerPostulantesPorRequerimiento(req.getId());
                        if (listaPost.isEmpty()) {
                            msg = UtilCore.Internacionalizacion.getMensajeInternacional("convocatoria.msg.val.postulantes");
                            return msg;
                        }
                    }
                }
            }
        } catch (Exception ex) {
            logger.error("ERROR DE SISTEMA", ex);
            recursosManager.showError(ex.getMessage());
        }

        return msg;
    }

    public ConvocatoriaDto publicar(ConvocatoriaDto dto) {
        ConvocatoriaDto to = null;
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        String msg = this.validarPublicacion(dto);
        if (msg.equals("")) {
            dto.setFechaPublicacion(UtilCore.Fecha.obtenerFechaActualDate());
            dto.setUsuarioPublicacion(sessionMBean.getSessionUsuarioDto().getId());
            dto.setEstadoDto(new ParametroDto(ConstantesSele.Parametro.CONV_ESTADO_PUBLICADA));
            to = this.guardar(dto, dto.getListaConvocatoriaEvaluacion());
        } else {
            recursosManager.showWarning(msg);
            to = null;
        }
        return to;
    }

    public ConvocatoriaDto anular(ConvocatoriaDto dto) {
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        dto.setFechaAnulacion(UtilCore.Fecha.obtenerFechaActualDate());
        dto.setUsuarioAnulacion(sessionMBean.getSessionUsuarioDto().getId());
        dto.setEstadoDto(new ParametroDto(ConstantesSele.Parametro.CONV_ESTADO_ANULADA));
        return this.guardar(dto, dto.getListaConvocatoriaEvaluacion());
    }

    public ConvocatoriaDto cerrar(ConvocatoriaDto dto) {
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        dto.setFechaCerrar(UtilCore.Fecha.obtenerFechaActualDate());
        dto.setUsuarioCerrar(sessionMBean.getSessionUsuarioDto().getId());
        dto.setEstadoDto(new ParametroDto(ConstantesSele.Parametro.CONV_ESTADO_CERRADA));
        return this.guardar(dto, dto.getListaConvocatoriaEvaluacion());
    }

    public ConvocatoriaDto terminar(ConvocatoriaDto dto) {
        ConvocatoriaDto to = null;
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        try {
            Boolean indicador = true;
            dto = obtenerConvocatoriaPorId(dto.getId());
            //Verificar si todos los requerimientos asociados ya han sido evaluados
            for (RequerimientoDto req : dto.getListaConvocaRequerimiento()) {
                if (!req.getEstadoDto().getId().equals(ConstantesSele.Parametro.REQ_ESTADO_EVALUADO)) {
                    indicador = false;
                }
            }
            if (indicador) {
                dto.setFechaTermino(UtilCore.Fecha.obtenerFechaActualDate());
                dto.setUsuarioTermino(sessionMBean.getSessionUsuarioDto().getId());
                dto.setEstadoDto(new ParametroDto(ConstantesSele.Parametro.CONV_ESTADO_TERMINADA));
                to = this.guardar(dto, dto.getListaConvocatoriaEvaluacion());
            } else {
                recursosManager.showWarning(UtilCore.Internacionalizacion.getMensajeInternacional("convocatoria.mensaje.no.requerimientos.evaluados"));
                to = null;
            }
        } catch (Exception ex) {
            logger.error("ERROR DE SISTEMA", ex);
            recursosManager.showError(ex.getMessage());
        }
        return to;
    }

    public List<ConvocatoriaDto> obtenerConFiltroConOrden(Map<String, Object> filtros, Map<String, String> orden) throws DAOException {
        return springHibernateDao.obtenerDtosConFiltrosConOrden(ConvocatoriaDto.class, filtros, orden);
    }
}
